package com.corticon.dialogs.dao.hibernate;

import static org.hibernate.criterion.Restrictions.*;

import java.util.List;

import org.apache.commons.lang.StringUtils;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;

import org.springframework.stereotype.Repository;

import com.corticon.dialogs.dao.UserDAO;
import com.corticon.dialogs.model.User;
import com.corticon.dialogs.util.Pager;

/**
 * Annotation Repository is used to register a DAO component into Spring Application Context. Do not
 * need to write <bean> in applicationContext.xml anymore.
 *
 * @author Lifan Yang
 */
@Repository("userDAO")
public class UserHibernateDAO extends GenericHibernateDAO<User, String> implements UserDAO {

    @Override
    public long getSearchCount(String keywords, String groupName, Boolean isEnabled) {
        return getCount(buildSearchCriteria(keywords, groupName, isEnabled));
    }

    @Override
    public List<User> search(String keywords, String groupName, Boolean isEnable, Pager pager) {
        return getPageOfData(buildSearchCriteria(keywords, groupName, isEnable), pager);
    }

    private Criteria buildSearchCriteria(String keywords, String groupName, Boolean isEnabled) {
        Criteria searchCriteria = getBaseCriteria();

        if (StringUtils.isNotBlank(keywords)) {
            keywords = keywords.trim();
            searchCriteria.add(disjunction().add(ilike("username", keywords, MatchMode.ANYWHERE)).add(
                ilike("firstname", keywords, MatchMode.ANYWHERE)).add(ilike("lastname", keywords,
                MatchMode.ANYWHERE)).add(ilike("email", keywords, MatchMode.ANYWHERE)));
        }


        if (StringUtils.isNotBlank(groupName)) {
            searchCriteria.add(conjunction().add(eq("userGroup.name", groupName)));
        }

        if (isEnabled != null) {
            searchCriteria.add(conjunction().add(eq("enabled", isEnabled)));
        }

        return searchCriteria;
    }

    @Override
    public List<User> findByGroup(String groupName) {
        Criteria criteria = getBaseCriteria();
        criteria.createCriteria("userGroup").add(eq("name", groupName));
        return criteria.list();
    }
}
